{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "64ed3b7d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 0.7390851360910594\n",
      "f(x) = 4.813138776427195e-09\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "import math\n",
    "\n",
    "class Particle:\n",
    "    #初始化粒子群\n",
    "    def __init__(self, dim):\n",
    "        self.position = [random.uniform(-5, 5) for i in range(dim)]\n",
    "        self.velocity = [random.uniform(-1, 1) for i in range(dim)]\n",
    "        self.best_position = self.position.copy()\n",
    "        self.best_fitness = float('inf')\n",
    "\n",
    "    def update_velocity(self, global_best_position, inertia_weight, cognitive_weight, social_weight):\n",
    "        for i in range(len(self.velocity)):\n",
    "            r1 = random.uniform(0, 1)\n",
    "            r2 = random.uniform(0, 1)\n",
    "            cognitive_component = cognitive_weight * r1 * (self.best_position[i] - self.position[i])\n",
    "            social_component = social_weight * r2 * (global_best_position[i] - self.position[i])\n",
    "            self.velocity[i] = inertia_weight * self.velocity[i] + cognitive_component + social_component\n",
    "\n",
    "    def update_position(self):\n",
    "        for i in range(len(self.position)):\n",
    "            self.position[i] += self.velocity[i]\n",
    "\n",
    "    def evaluate_fitness(self):\n",
    "        x = self.position[0]\n",
    "        f = math.cos(x) - x\n",
    "        self.fitness = abs(f)\n",
    "        if self.fitness < self.best_fitness:\n",
    "            self.best_fitness = self.fitness\n",
    "            self.best_position = self.position.copy()\n",
    "\n",
    "class PSO:\n",
    "    def __init__(self, num_particles, dim, max_iter):\n",
    "        self.num_particles = num_particles\n",
    "        self.dim = dim\n",
    "        self.max_iter = max_iter\n",
    "        self.particles = [Particle(dim) for i in range(num_particles)]\n",
    "        self.global_best_position = None\n",
    "        self.global_best_fitness = float('inf')\n",
    "\n",
    "    def optimize(self):\n",
    "        for i in range(self.max_iter):\n",
    "            for particle in self.particles:\n",
    "                particle.evaluate_fitness()\n",
    "                if particle.fitness < self.global_best_fitness:\n",
    "                    self.global_best_fitness = particle.fitness\n",
    "                    self.global_best_position = particle.position.copy()\n",
    "            for particle in self.particles:\n",
    "                particle.update_velocity(self.global_best_position, 0.7, 1.4, 1.4)\n",
    "                particle.update_position()\n",
    "\n",
    "pso = PSO(num_particles=50, dim=1, max_iter=100)\n",
    "pso.optimize()\n",
    "print(\"x =\", pso.global_best_position[0])\n",
    "print(\"f(x) =\", pso.global_best_fitness)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0275c498",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'w' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[2], line 16\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m iteration \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(max_iterations):\n\u001b[0;32m     14\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m particle \u001b[38;5;129;01min\u001b[39;00m particles:\n\u001b[0;32m     15\u001b[0m         \u001b[38;5;66;03m# 更新粒子的速度和位置\u001b[39;00m\n\u001b[1;32m---> 16\u001b[0m         particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvelocity\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[43mw\u001b[49m \u001b[38;5;241m*\u001b[39m particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvelocity\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m+\u001b[39m c1 \u001b[38;5;241m*\u001b[39m random\u001b[38;5;241m.\u001b[39muniform(\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m*\u001b[39m (particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbest_position\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m-\u001b[39m particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mposition\u001b[39m\u001b[38;5;124m'\u001b[39m]) \u001b[38;5;241m+\u001b[39m c2 \u001b[38;5;241m*\u001b[39m random\u001b[38;5;241m.\u001b[39muniform(\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m*\u001b[39m (global_best_position \u001b[38;5;241m-\u001b[39m particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mposition\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m     17\u001b[0m         particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mposition\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mposition\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m+\u001b[39m particle[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvelocity\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m     19\u001b[0m         \u001b[38;5;66;03m# 计算粒子的适应度值\u001b[39;00m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'w' is not defined"
     ]
    }
   ],
   "source": [
    "# 初始化粒子群\n",
    "num_particles = 50\n",
    "max_iterations = 1000\n",
    "particles = []\n",
    "for i in range(num_particles):\n",
    "    position = random.uniform(-5, 5)\n",
    "    velocity = random.uniform(-5, 5)\n",
    "    particles.append({'position': position, 'velocity': velocity, 'fitness': float('inf'), 'best_position': position, 'best_fitness': float('inf')})\n",
    "    \n",
    "# 粒子群迭代\n",
    "global_best_fitness = float('inf')\n",
    "global_best_position = None\n",
    "for iteration in range(max_iterations):\n",
    "    for particle in particles:\n",
    "        # 更新粒子的速度和位置\n",
    "        particle['velocity'] = w * particle['velocity'] + c1 * random.uniform(0, 1) * (particle['best_position'] - particle['position']) + c2 * random.uniform(0, 1) * (global_best_position - particle['position'])\n",
    "        particle['position'] = particle['position'] + particle['velocity']\n",
    "        \n",
    "        # 计算粒子的适应度值\n",
    "        fitness = abs(cos(particle['position']) - particle['position'])\n",
    "        particle['fitness'] = fitness\n",
    "        \n",
    "        # 更新个体最优解\n",
    "        if fitness < particle['best_fitness']:\n",
    "            particle['best_fitness'] = fitness\n",
    "            particle['best_position'] = particle['position']\n",
    "            \n",
    "        # 更新全局最优解\n",
    "        if fitness < global_best_fitness:\n",
    "            global_best_fitness = fitness\n",
    "            global_best_position = particle['position']\n",
    "            \n",
    "    # 判断停止条件\n",
    "    if global_best_fitness < 1e-6:\n",
    "        break\n",
    "        \n",
    "# 返回最优解\n",
    "print('x =', global_best_position)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dff2700a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
